package ru.alexbykov.nopaginate.paginate;

import ohos.agp.components.BaseItemProvider;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;

import ru.alexbykov.nopaginate.callback.OnRepeatListener;
import ru.alexbykov.nopaginate.item.ErrorItem;
import ru.alexbykov.nopaginate.item.LoadingItem;

/**
 * Created by Alex Bykov on 11.08.2017.
 * You can contact me at: me@alexbykov.ru.
 */
public final class WrapperAdapter extends BaseItemProvider {
    private static final int ITEM_VIEW_TYPE_LOADING = 46699933;
    private static final int ITEM_VIEW_TYPE_ERROR = 46699932;

    private BaseItemProvider userAdapter;
    private LoadingItem loadingItem;
    private ErrorItem errorItem;
    private PaginateStatus paginateStatus = PaginateStatus.LOADING;
    private OnRepeatListener repeatListener;

    WrapperAdapter(BaseItemProvider userAdapter, LoadingItem loadingItem, ErrorItem errorItem) {
        this.userAdapter = userAdapter;
        this.loadingItem = loadingItem;
        this.errorItem = errorItem;
    }

    @Override
    public int getItemComponentType(int position) {
        if (isLoadingItem(position)) {
            return ITEM_VIEW_TYPE_LOADING;
        } else if (isErrorItem(position)) {
            return ITEM_VIEW_TYPE_ERROR;
        } else {
            return userAdapter.getItemComponentType(position);
        }
    }

    @Override
    public Component getComponent(int position, Component component, ComponentContainer componentContainer) {
        if (getItemComponentType(position) == ITEM_VIEW_TYPE_LOADING) {
            return loadingItem.getComponent(position, component, componentContainer);
        } else if (getItemComponentType(position) == ITEM_VIEW_TYPE_ERROR) {
            return errorItem.getComponent(position, component, componentContainer, repeatListener);
        } else {
            return userAdapter.getComponent(position, component, componentContainer);
        }
    }

    private boolean isErrorItem(int position) {
        return paginateStatus == PaginateStatus.ERROR && position == getErrorOrLoadingItemPosition();
    }

    private boolean isLoadingItem(int position) {
        return paginateStatus == PaginateStatus.LOADING && position == getErrorOrLoadingItemPosition();
    }

    private int getErrorOrLoadingItemPosition() {
        return isErrorOrLoading() ? getCount() - 1 : -1;
    }

    private boolean isErrorOrLoading() {
        return paginateStatus == PaginateStatus.LOADING || paginateStatus == PaginateStatus.ERROR;
    }

    @Override
    public int getCount() {
        return isErrorOrLoading() ? userAdapter.getCount() + 1 : userAdapter.getCount();
    }

    void stateChanged(PaginateStatus status) {
        if (this.paginateStatus != status) {
            this.paginateStatus = status;
            notifyDataChanged();
        }
    }

    void setRepeatListener(OnRepeatListener repeatListener) {
        this.repeatListener = repeatListener;
    }

    void unbind() {
        repeatListener = null;
    }

    @Override
    public Object getItem(int position) {
        return userAdapter.getItem(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }
}
